//
//  RequestManager.m
//  Libraries
//
//  Created by 侯伟 on 2018/10/11.
//  Copyright © 2018年 侯伟. All rights reserved.
//

#import "RequestManager.h"
#import <AFNetworking/AFNetworking.h>


@interface RequestManager ()

@property (nonatomic, strong) AFHTTPSessionManager *manager;

@property (nonatomic, strong) NSDictionary *headers;

@end

@implementation RequestManager

- (id)init{
    if (self = [super init]){
        [self initManager];
    }
    return self;
}


- (void)initManager{
    
    AFHTTPSessionManager* _manager = [AFHTTPSessionManager manager];
    
    ///config
    NSURLSessionConfiguration* _config = _manager.session.configuration;
    _config.timeoutIntervalForRequest = 10.f;
    _config.timeoutIntervalForResource = 10.f;
    _config.requestCachePolicy  = NSURLRequestReturnCacheDataElseLoad;
    _config.HTTPCookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    
    ///request
    
    AFJSONRequestSerializer* requestSerializer = [AFJSONRequestSerializer serializer];
    _manager.requestSerializer = requestSerializer;
    
    ///response
    AFJSONResponseSerializer* responseSerializer = [AFJSONResponseSerializer serializer];
    responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html",@"text/xml",@"image/jpeg",@"image/png", @"application/octet-stream", @"multipart/form-data",@"text/plain",nil];
    _manager.responseSerializer = responseSerializer;
    
    
    ///securityPolicy
    AFSecurityPolicy* securityPolicy = [AFSecurityPolicy defaultPolicy];
    securityPolicy.allowInvalidCertificates = YES;
    securityPolicy.validatesDomainName = NO;
    _manager.securityPolicy = securityPolicy;
    
    self.manager = _manager;
}

#pragma mark -------------------- public --------------------

+ (instancetype)sharedInstance
{
    static RequestManager *instance = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

- (void)setRequestHeader:(NSDictionary *)requestHeader{
    
    _headers = requestHeader;
    
    [self.manager.requestSerializer clearAuthorizationHeader];
    
    if(requestHeader.count){
        [requestHeader enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            [self.manager.requestSerializer setValue:obj forHTTPHeaderField:key];
        }];
    }
}

/**
 *  通用
 *  网络请求
 */
- (void)requestWithURL:(NSString *)url method:(RequestMethod)method params:(NSDictionary *)params callback:(RequestResult)callback{
    
    [self callWithURL:url method:method params:params success:^(id response) {
        if (callback){
            callback(response,YES);
        }
        
    } failure:^(NSError *error) {
        if (callback){
            callback(error,NO);
        }
    }];
}


- (void)callWithURL:(NSString *)url method:(RequestMethod)method params:(NSDictionary *)params success:(void(^)(id response))success failure:(void(^)(NSError* error))failure{
    switch (method)
    {
        case MethodGET:
        {
            [self get:url params:params success:success failure:failure];
        }
            break;
        case MethodPOST:
        {
            [self post:url params:params success:success failure:failure];
        }
            break;
        case MethodPUT:
        {
            [self put:url params:params success:success failure:failure];
        }
            break;
        case MethodDELETE:
        {
            [self deleteWithUrl:url params:params success:success failure:failure];
        }
            break;
        case MethodPATCH:
        {
            [self patchWithUrl:url params:params success:success failure:failure];
        }
            break;
        default:
            break;
    }
}


#pragma mark -------------------- private --------------------



- (void)get:(NSString *)url params:(NSDictionary *)params success:(void(^)(id response))success failure:(void(^)(NSError* error))failure{
    
    [self.manager GET:url parameters:params headers:self.headers progress:NULL success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if(success){
            success(responseObject);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if(failure){
            failure(error);
        }
    }];
}

- (void)post:(NSString *)url params:(NSDictionary *)params success:(void(^)(id response))success failure:(void(^)(NSError* error))failure{
    
    [self.manager POST:url parameters:params headers:self.headers progress:NULL success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if(success){
            success(responseObject);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if(failure){
            failure(error);
        }
    }];
}

- (void)put:(NSString *)url params:(NSDictionary *)params success:(void(^)(id response))success failure:(void(^)(NSError* error))failure{
    
    [self.manager PUT:url parameters:params headers:self.headers success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if(success){
            success(responseObject);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if(failure){
            failure(error);
        }
    }];
}

- (void)deleteWithUrl:(NSString *)url params:(NSDictionary *)params success:(void(^)(id response))success failure:(void(^)(NSError* error))failure{
    
    [self.manager DELETE:url parameters:params headers:self.headers success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if(success){
            success(responseObject);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if(failure){
            failure(error);
        }
    }];
}

- (void)patchWithUrl:(NSString *)url params:(NSDictionary *)params success:(void(^)(id response))success failure:(void(^)(NSError* error))failure{
    
    [self.manager PATCH:url parameters:params headers:self.headers success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if(success){
            success(responseObject);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if(failure){
            failure(error);
        }
    }];
}



- (void)cancelAllOperations{
    [self.manager.operationQueue cancelAllOperations];
}

@end
